﻿// ===============================================================================
// DotNet.Platform 开发框架 2016 版权所有
// ===============================================================================

using System.Collections.Generic;
using System.Linq;
using DotNet.Core.Entity;
using DotNet.Utility;
using DotNet.Helper;
using System;
using DotNet.Data.Extensions;
using DotNet.Extensions;

namespace DotNet.Core.Service
{
    /// <summary>
    /// 文章分类服务
    /// </summary>
    public class ArticleCategoryService
    {
        public readonly static ArticleCategoryService Instance = new ArticleCategoryService();
        private CoreRepository<ArticleCategory> repos = new CoreRepository<ArticleCategory>();
        private static Cache<string, ArticleCategory> Cache;

        /// <summary>
        /// 构造服务
        /// </summary>
        private ArticleCategoryService()
        {
            Cache = new Cache<string, ArticleCategory>();
            InitCache();
        }

        /// <summary>
        /// 初始化缓存
        /// </summary>
        public void InitCache()
        {
            var dic = repos.Query().ToDictionary(p => p.Id, p => p);
            Cache.Clear().Set(dic);
        }

        /// <summary>
        /// 是否存在指定名称的对象
        /// </summary>
        /// <param name="id">主键</param>
        /// <param name="name">名称</param>
        /// <returns>存在返回false</returns>
        public BoolMessage ExistsByName(string id, string parentid,string name)
        {
            var has = Cache.ValueList().Contains(p => p.Name.Equals(name) && p.ParentId== parentid && !p.Id.Equals(id));
            return has ? new BoolMessage(false, "指定的名称已经存在") : BoolMessage.True;
        }

        /// <summary>
        /// 添加对象
        /// </summary>
        /// <param name="entity">实体</param>
        public BoolMessage Create(ArticleCategory entity)
        {
            repos.Insert(entity);
            Cache.Set(entity.Id, entity);
            return BoolMessage.True;
        }

        /// <summary>
        /// 更新对象
        /// </summary>
        /// <param name="entity">实体</param>
        public BoolMessage Update(ArticleCategory entity)
        {
            repos.Update(entity);
            Cache.Set(entity.Id, entity);
            return BoolMessage.True;
        }

        /// <summary>
        /// 保存对象
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="isCreate">是否新增</param>
        public BoolMessage Save(ArticleCategory entity, bool isCreate)
        {
            return isCreate ? Create(entity) : Update(entity);
        }

        /// <summary>
        /// 删除对象(删除包括所有子节点以及所有子节点)
        /// </summary>
        /// <param name="id">主键</param>
        public BoolMessage Delete(string id)
        {
            if (!Cache.Contains(id)) return new BoolMessage(false, "找不到指定主键的数据");
            var childs = GetChildNodeList(id, true);
            var ids = childs.Select(p => p.Id).ToArray();
            repos.Delete(ids);
            Cache.Remove(ids);
            return BoolMessage.True;
        }

        /// <summary>
        /// 保存指定对象父节点
        /// </summary>
        /// <param name="id">主键</param>
        /// <param name="newParentId">新父节点主键</param>
        public BoolMessage SaveParent(string id, string newParentId)
        {
            repos.Update(new ArticleCategory { Id = id, ParentId = newParentId }, p => p.ParentId);
            var entity = Cache.Get(id);
            if (entity != null) entity.ParentId = newParentId;
            return BoolMessage.True;
        }

        /// <summary>
        /// 保存对象节点排序路径
        /// </summary>
        /// <param name="sortPaths">更改的数据</param>
        public BoolMessage SaveSortPath(PrimaryKeyValue[] sortPaths)
        {
            repos.BatchUpdate(sortPaths);
            sortPaths.ForEach(p =>
            {
                var entity = Cache.Get(p.Id);
                if (entity != null) entity.SortPath = p.Value;
            });
            return BoolMessage.True;
        }

        /// <summary>
        /// 获取新建节点排序路径
        /// </summary>
        /// <param name="parendId">新建节点的父主键</param>
        public string GetNewSortPath(string parendId)
        {
            var entity = Cache.Get(parendId);
            return TreeHelper.GetNewNodeSortPath(Cache.ValueList(), entity);
        }
         
        /// <summary>
        /// 获取指定节点主键的所有子节点集合
        /// </summary>
        /// <param name="id">节点主键</param>
        /// <param name="containSelf">是否包含指定节点对象</param>
        public List<ArticleCategory> GetChildNodeList(string id, bool containSelf)
        {
            var entity = Cache.Get(id);
            CheckEntityNull(entity, paramName: nameof(id));
            return TreeHelper.GetAllChilds(Cache.ValueList(), entity, containSelf);
        }

        private void CheckEntityNull(ArticleCategory entity,
            string message = "指定的节点主键有误,找不到对应的数据记录",
            string paramName = null)
        {
            if (entity == null)
            {
                throw new ArgumentException(message, paramName);
            }
        }

        /// <summary>
        /// 获取对象
        /// </summary>
        public ArticleCategory GetById(string id)
        {
            return Cache.Get(id);
        }

        /// <summary>
        /// 获取启用的对象集合
        /// </summary>
        public List<ArticleCategory> GetList(string name = null)
        {
            if (string.IsNullOrEmpty(name))
            {
                return Cache.ValueList().OrderByAsc(p => p.SortPath);
            }
            return Cache.ValueList()
                .Where(p => p.Name.Contains(name))
                .ToList().OrderByAsc(p => p.SortPath);
        }

        /// <summary>
        /// 获取名称列表
        /// </summary>
        public List<ArticleCategory> GetCaptionList(string parentId)
        {
            return Cache.ValueList()
                .Where(p => p.ParentId == parentId)
                .ToList().OrderByAsc(p => p.SortPath);
        }

        /// <summary>
        /// 获取第一个名称
        /// </summary>
        public ArticleCategory GetFirstCaption(string parentId)
        {
            return Cache.ValueList()
                .Where(p => p.ParentId == parentId)
                .ToList().OrderByAsc(p => p.SortPath).FirstOrDefault();
        }

        /// <summary>
        /// 获取第一个名称
        /// </summary>
        public ArticleCategory GetParent(string id)
        {
            var entity = Cache.Get(id);
            if (entity != null)
            {
                return Cache.Get(entity.ParentId);
            }
            return new ArticleCategory();
        }

        /// <summary>
        /// 获取启用的简单对象集合
        /// </summary>
        public List<Simple> GetSimpleList()
        {
            return Cache.ValueList()
                .Select(p => new Simple(p.Id, p.Name, p.Name.Spell()))
                .ToList();
        }
    }
}
